<template>
  <JVxeTable
    ref="tableRef"
    row-class-name="online-config-page"
    row-number
    keyboardEdit
    :maxHeight="tableHeight.noToolbar"
    :loading="loading"
    :columns="columns"
    :dataSource="dataSource"
    :disabledRows="{ dbFieldName: ['id', 'has_child'] }"
    v-bind="tableProps"
  >
    <template #fieldConfig="props">
      <a-button v-if="showConfigButton(props)" title="打开配置" type="primary" size="small" ghost @click="openConfig(props)">打开配置</a-button>
    </template>
  </JVxeTable>
  <LinkTableConfigModal @register="registerModal" @success="handleConfigData" />
  <LinkTableFieldConfigModal @register="registerFieldModal" @success="handleFieldConfigData" />
  <FieldExtendJsonModal @register="registerExtJsonModal" @success="handleExtJson" />
</template>

<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
  import LinkTableConfigModal from '../../extend/linkTable/LinkTableConfigModal.vue';
  import LinkTableFieldConfigModal from '../../extend/linkTable/LinkTableFieldConfigModal.vue';
  import FieldExtendJsonModal from '../../extend/FieldExtendJsonModal.vue';
  import { useTableSync } from '../../use/useTableSync';
  import { useModal } from '/@/components/Modal';

  const commonPageOptions = [
    { title: '文本框', value: 'text' },
    { title: '密码', value: 'password' },
    { title: '下拉框', value: 'list' },
    { title: '单选框', value: 'radio' },
    { title: '多选框', value: 'checkbox' },
    { title: '开关', value: 'switch' },
    { title: '日期(年月日)', value: 'date' },
    { title: '日期(年月日时分秒)', value: 'datetime' },
    { title: '时间(HH:mm:ss)', value: 'time' },
    { title: '文件', value: 'file' },
    { title: '图片', value: 'image' },
    { title: '多行文本', value: 'textarea' },
    { title: '富文本', value: 'umeditor' },
    { title: 'MarkDown', value: 'markdown' },
    { title: '用户选择', value: 'sel_user' },
    { title: '部门选择', value: 'sel_depart' },
    { title: '关联记录', value: 'link_table' },
    { title: '他表字段', value: 'link_table_field' },
    { title: '省市区组件', value: 'pca' },
    { title: 'Popup弹框', value: 'popup' },
    { title: '下拉多选框', value: 'list_multi' },
    { title: '下拉搜索框', value: 'sel_search' },
    { title: '分类字典树', value: 'cat_tree' },
    { title: '自定义树控件', value: 'sel_tree' },
    { title: '联动组件', value: 'link_down' },
  ];
  const subTablePageOptions = [
    { title: '文本框', value: 'text' },
    { title: '单选框', value: 'radio' },
    { title: '开关', value: 'switch' },
    { title: '日期(yyyy-MM-dd)', value: 'date' },
    { title: '日期(yyyy-MM-dd HH:mm:ss)', value: 'datetime' },
    { title: '时间(HH:mm:ss)', value: 'time' },
    { title: '文件', value: 'file' },
    { title: '图片', value: 'image' },
    { title: '下拉框', value: 'list' },
    { title: '下拉多选框', value: 'list_multi' },
    { title: '下拉搜索框', value: 'sel_search' },
    { title: 'popup弹出框', value: 'popup' },
    { title: '部门选择', value: 'sel_depart' },
    { title: '用户选择', value: 'sel_user' },
    { title: '省市区组件', value: 'pca' },
    { title: '多行文本', value: 'textarea' },
  ];

  export default defineComponent({
    name: 'PageAttributeTable',
    components: {
      LinkTableConfigModal,
      LinkTableFieldConfigModal,
      FieldExtendJsonModal,
    },
    setup() {
      const columns = ref([
        { title: '字段名称', key: 'dbFieldName', width: 100 },
        { title: '字段备注', key: 'dbFieldTxt', width: 100 },
        {
          title: '表单显示',
          key: 'isShowForm',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: true,
        },
        {
          title: '列表显示',
          key: 'isShowList',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: true,
        },
        {
          title: '是否排序',
          key: 'sortFlag',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: false,
        },
        {
          title: '是否只读',
          key: 'isReadOnly',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: false,
        },
        {
          title: '控件类型',
          key: 'fieldShowType',
          width: 170,
          type: JVxeTypes.select,
          options: commonPageOptions,
          defaultValue: 'text',
          placeholder: '请选择${title}',
          validateRules: [{ required: true, message: '请选择${title}' }, { handler: validateFieldShowType }],
        },
        {
          title: '控件长度',
          key: 'fieldLength',
          width: 120,
          titleHelp: { message: '此长度只对子表列字段宽度有效！' },
          type: JVxeTypes.inputNumber,
          defaultValue: 200,
          placeholder: '请输入${title}',
          validateRules: [{ required: true, message: '${title}不能为空' }],
        },
        {
          title: '是否查询',
          key: 'isQuery',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: false,
        },
        {
          title: '查询类型',
          key: 'queryMode',
          width: 110,
          type: JVxeTypes.select,
          options: [
            { title: '普通查询', value: 'single' },
            { title: '范围查询', value: 'group' },
          ],
          defaultValue: 'single',
          placeholder: '请选择${title}',
          validateRules: [{ required: true, message: '请选择${title}' }],
        },
        {
          title: '控件默认值',
          key: 'fieldDefaultValue',
          width: 120,
          type: JVxeTypes.input,
          defaultValue: '',
        },
        {
          title: '定义转换器',
          key: 'converter',
          width: 150,
          type: JVxeTypes.input,
          defaultValue: '',
        },
        {
          title: '扩展参数',
          key: 'fieldExtendJson',
          width: 120,
          type: JVxeTypes.input,
          defaultValue: '',
        },
        {
          title: '更多配置',
          minWidth: 100,
          key: 'fieldConfig',
          type: JVxeTypes.slot,
          slotName: 'fieldConfig',
        },
      ]);
      const setup = useTableSync(columns);
      const { tableRef, tables } = setup;
      function validateFieldShowType({ cellValue, row }, callback) {
        let { dbTable } = tables;
        let dbType = dbTable.value.tableRef.getTableData({ rowIds: [row.id] })[0].dbType;
        if (cellValue === 'time' && dbType !== 'string') {
          callback(false, '当控件类型为时间时,数据库属性里的字段类型必须是String！');
        } else if (cellValue === 'date' && dbType !== 'Date' && dbType !== 'Datetime') {
          callback(false, '当控件类型为日期时，数据库属性里的字段类型必须是Date或Datetime！');
        } else if (cellValue === 'datetime' && dbType !== 'Datetime') {
          callback(false, '当控件类型为datetime时，数据库属性里的字段类型必须是Datetime！');
        } else {
          callback(true);
        }
      }
      function syncFieldShowType(row) {
        let showType = 'date';
        if (row.dbType === 'Datetime') {
          showType = 'datetime';
        }
        tableRef.value.setValues([
          {
            rowKey: row.id,
            values: { fieldShowType: showType },
          },
        ]);
      }
      function changePageType(flag) {
        for (let col of columns.value) {
          if (col.key == 'fieldShowType') {
            col.options = !flag ? commonPageOptions : subTablePageOptions;
            break;
          }
        }
      }
      function enableQuery(id) {
        tableRef.value.setValues([
          {
            rowKey: id,
            values: { isQuery: '1' },
          },
        ]);
      }
      const [registerModal, { openModal }] = useModal();
      const [registerFieldModal, { openModal: openFieldModal }] = useModal();
      const [registerExtJsonModal, { openModal: openExtJsonModal }] = useModal();
      function showConfigButton(props) {
        if (props.row.dbFieldName == 'id') {
          return false;
        } else {
          return true;
        }
      }
      function openConfig(props) {
        if (props.row.fieldShowType.indexOf('link_table') >= 0) {
          showFieldConfig(props);
        } else {
          showExtJsonConfig(props);
        }
      }
      function showFieldConfig(props) {
        let { row } = props;
        let { checkTable } = tables;
        if (checkTable) {
          let checkTableValue = checkTable.value.tableRef.getTableData({ rowIds: [row.id] })[0];
          if (props.row.fieldShowType == 'link_table') {
            let record = getLinkTableModalData(row, checkTableValue);
            openModal(true, {
              record,
              fieldName: row.dbFieldName,
            });
          } else if (props.row.fieldShowType == 'link_table_field') {
            let data = getLinkTableFieldData(row, checkTableValue);
            openFieldModal(true, data);
          }
        }
      }
      function getLinkTableFieldData(row, checkTableValue) {
        let tableData = tableRef.value.getTableData();
        let pageTableData = tableData.filter((item) => item.fieldShowType == 'link_table');
        let tableAndFieldsMap = {};
        if (pageTableData && pageTableData.length > 0) {
          let checkTableData = tables.checkTable.value.tableRef.getTableData();
          for (let pageTable of pageTableData) {
            let tempArray = checkTableData.filter((i) => i.dbFieldName == pageTable.dbFieldName);
            if (tempArray && tempArray.length > 0) {
              let item = tempArray[0];
              tableAndFieldsMap[item.dbFieldName] = {
                title: pageTable.dbFieldTxt,
                table: item.dictTable,
                fields: item.dictText,
              };
            }
          }
        }
        const { dictTable, dictText } = checkTableValue;
        const { id, dbFieldTxt } = row;
        let record = {
          rowKey: id,
          dbFieldTxt,
          dictText,
          dictTable,
        };
        return {
          record,
          tableAndFieldsMap,
        };
      }
      function getLinkTableModalData(row, checkTableValue) {
        const { id, dbFieldTxt, fieldExtendJson } = row;
        const { dictTable, dictText } = checkTableValue;
        let result = {
          rowKey: id,
          dbFieldTxt,
          dictTable,
        };
        if (dictText) {
          let arr = dictText.split(',');
          result['titleField'] = arr[0];
          if (arr.length > 1) {
            result['otherFields'] = dictText.substring(dictText.indexOf(',') + 1);
          }
        } else {
          result['titleField'] = '';
          result['otherFields'] = '';
        }
        if (fieldExtendJson) {
          try {
            let json = JSON.parse(fieldExtendJson);
            if (json.multiSelect) {
              result['multiSelect'] = json.multiSelect;
            } else {
              result['multiSelect'] = false;
            }
            if (json.showType) {
              result['showType'] = json.showType;
            } else {
              result['showType'] = 'card';
            }
            if (json.imageField) {
              result['imageField'] = json.imageField;
            } else {
              result['imageField'] = '';
            }
          } catch (e) {
            console.error('解析扩展参数出错', fieldExtendJson);
          }
        }
        return result;
      }
      function handleConfigData(record) {
        const { multiSelect, showType, imageField, fieldName } = record;
        let extJson = { showType, multiSelect, imageField };
        let values = [{ rowKey: record.rowKey, values: { fieldExtendJson: JSON.stringify(extJson), dbFieldTxt: record.dbFieldTxt } }];
        tableRef.value.setValues(values);
        let { checkTable, dbTable } = tables;
        if (dbTable) {
          let dbTableValues = [{ rowKey: record.rowKey, values: { dbFieldTxt: record.dbFieldTxt } }];
          dbTable.value.tableRef.setValues(dbTableValues);
        }
        if (checkTable) {
          let dictText = record.titleField;
          if (record.otherFields) {
            dictText += ',' + record.otherFields;
          }
          const { dictTable, dictField } = record;
          let temp = {
            dictTable,
            dictField,
            dictText,
            dbFieldName: fieldName,
          };
          let dbTableValues = [{ rowKey: record.rowKey, values: temp }];
          checkTable.value.tableRef.setValues(dbTableValues);
        }
      }
      function handleFieldConfigData(record) {
        const { dbFieldTxt, dictTable, dictText, rowKey } = record;
        let values = [{ rowKey, values: { dbFieldTxt } }];
        tableRef.value.setValues(values);
        let { checkTable, dbTable } = tables;
        if (dbTable) {
          let tableValues = [{ rowKey, values: { dbFieldTxt, dbIsPersist: '0' } }];
          dbTable.value.tableRef.setValues(tableValues);
        }
        if (checkTable) {
          let tableValues = [{ rowKey, values: { dictTable, dictText } }];
          checkTable.value.tableRef.setValues(tableValues);
        }
      }
      function showExtJsonConfig(props) {
        let jsonStr = props.row.fieldExtendJson || '';
        let id = props.rowId;
        let fieldShowType = props.row.fieldShowType || '';
        let sortFlag = props.row.sortFlag || '0';
        openExtJsonModal(true, {
          jsonStr,
          fieldShowType,
          sortFlag,
          id,
        });
      }
      function handleExtJson(data, rowKey) {
        let values;
        if (data && Object.keys(data).length > 0) {
          values = [{ rowKey, values: { fieldExtendJson: JSON.stringify(data) } }];
        } else {
          values = [{ rowKey, values: { fieldExtendJson: '' } }];
        }
        tableRef.value.setValues(values);
      }
      return Object.assign({}, setup, {
        columns,
        enableQuery,
        syncFieldShowType,
        changePageType,
        showConfigButton,
        showFieldConfig,
        registerExtJsonModal,
        handleExtJson,
        openConfig,
        registerModal,
        handleConfigData,
        registerFieldModal,
        handleFieldConfigData,
      });
    },
  });
</script>
<style scoped lang="less">
  .online-config-page td:last-child.col--selected {
    box-shadow: none !important;
  }
</style>
